"""
线程和计时器
"""


import sys
from typing import Optional
from datetime import datetime
from PySide6.QtCore import QThread, QTimer
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QPushButton, QVBoxLayout, QWidget)


class ThreadTimerWidget(QWidget):
    def __init__(self, parent: Optional[QWidget] = None) -> None:
        super().__init__(parent=parent)
        self.__init_subwidget()
        self.__init_timer()
        self.__init_thread()
        self.__init_connect()
        self.__init_layout()

    def __init_subwidget(self):
        self.timer_label = QLabel("")
        self.timer_button = QPushButton("阻塞5秒")
        self.unblock_timer_button = QPushButton("非阻塞5秒")
        self.force_stop_button = QPushButton("强制停止非阻塞")

    def __init_timer(self):
        self.timer = QTimer(self)
        self.timer.start(100)

    def __init_connect(self):
        self.timer_button.clicked.connect(self.__slot_blocked)
        self.timer.timeout.connect(self.__slot_update_timer)
        self.unblock_timer_button.clicked.connect(self.thread.start)   # 启动线程，调用run方法，但不会重复
        self.thread.finished.connect(self.__slot_add_timer)     # 设置线程完成时调用
        self.force_stop_button.clicked.connect(self.thread.terminate)   # 设置线程强制停止
    
    def __init_thread(self):
        self.thread = QThread()
        self.thread.run = self.__slot_unblocked             # 设置运行时调用

    def __init_layout(self):
        vbox = QVBoxLayout()
        self.setMinimumSize(800, 600)
        vbox.addWidget(self.timer_label)
        vbox.addWidget(self.timer_button)
        vbox.addWidget(self.unblock_timer_button)
        vbox.addWidget(self.force_stop_button)
        self.setLayout(vbox)

    def __slot_blocked(self): 
        QThread.sleep(5)   # 主进程锁定5秒
        self.__slot_add_timer()
    
    def __slot_add_timer(self):
        timer_label = QLabel(datetime.now().__str__())
        self.layout().addWidget(timer_label)

    def __slot_unblocked(self): 
        self.thread.setPriority(QThread.LowestPriority)     # 设置线程优先级
        self.thread.sleep(5)   # 主进程锁定5秒
    def __slot_update_timer(self): self.timer_label.setText(datetime.now().__str__())
        

if __name__ == "__main__":
    # 主流程控制，一个程序只能有一个QApplication，sys可以用于命令行导入
    app = QApplication(sys.argv)
    window = ThreadTimerWidget()
    window.show()
    sys.exit(app.exec())               # 控制程序安全退出
